/*
 * HIPS Scheduling
 * Copyright (C) 2009 RedHipps Software
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.redhipps.hips.client.command;

import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Widget;
import com.redhipps.hips.client.HipsApp;
import com.redhipps.hips.client.io.IOService;
import com.redhipps.hips.client.io.ReaderCallback;
import com.redhipps.hips.client.model.Context;
import com.redhipps.hips.client.model.Institution;
import com.redhipps.hips.client.model.Schedule;
import com.redhipps.hips.client.model.ScheduleSolution;
import com.redhipps.hips.client.widget.SchedulingView;
import com.redhipps.hips.client.widget.SelectionListener;

public class InstitutionDetailsCommand extends HipsCommand<Institution> {

  @Override
  public void execute(final AsyncCallback<Institution> callback) {
    final Context context = context();
    final Grid grid = new Grid(2, 1);
    final SchedulingView schedulingView = new SchedulingView(context,
        ioService(), requestBuilderFactory());
    schedulingView.setScheduleSelectionListener(new ScheduleSelectionListener());
    schedulingView.setScheduleSolutionSelectionListener(new ScheduleSolutionSelectionListener());
    grid.setWidget(0, 0, new Label("Back"));
    grid.setWidget(1, 0, schedulingView);
    grid.setWidth("100%");
    HipsApp.setContents(grid);

    ReaderCallback<Institution> readerCallback = new ReaderCallback<Institution>() {
      public void onFailure(Throwable caught) {
        GWT.log("Institution load failed.", caught);
        callback.onFailure(caught);
      }
      public void onSuccess(List<Institution> result) {
        Institution institution = result.get(0);
        context.pushInstitution(institution);
        schedulingView.setDoctors(institution.getDoctors());
        schedulingView.setSchedules(institution.getSchedules());
        callback.onSuccess(institution);
      }
    };

    IOService ioService = ioService();
    ioService.read(context, Institution.class, context.institution().key(), readerCallback);
  }

  // TODO Move this into controller
  private class ScheduleSelectionListener implements SelectionListener<Schedule> {

    public void itemSelected(final Schedule model, Widget widget) {
      final IOService ioService = ioService();
      final Context context = context();
      final SchedulingView schedulingView = (SchedulingView) widget;
      ReaderCallback<Schedule> scheduleDetailsCallback = new ReaderCallback<Schedule>() {
        public void onFailure(Throwable caught) {
          GWT.log("Schedule load failed", caught);
        }
        public void onSuccess(List<Schedule> result) {
          Schedule schedule = result.get(0);
          context.pushSchedule(schedule);
          schedulingView.setDoctorConstraints(schedule.getDoctorConstraints());
          schedulingView.setSolutions(schedule.getScheduleSolutions());
        }
      };
      ioService.read(context, Schedule.class, model.key(), scheduleDetailsCallback);
    }
  }

  // TODO Move this into controller
  private class ScheduleSolutionSelectionListener implements SelectionListener<ScheduleSolution> {

    public void itemSelected(ScheduleSolution model, Widget widget) {
      final IOService ioService = ioService();
      final Context context = context();
      final SchedulingView schedulingView = (SchedulingView) widget;
      ReaderCallback<ScheduleSolution> solutionDetailsCallback =
          new ReaderCallback<ScheduleSolution>() {
        public void onFailure(Throwable caught) {
          GWT.log("Schedule load failed", caught);
        }
        public void onSuccess(List<ScheduleSolution> result) {
          ScheduleSolution solution = result.get(0);
          context.pushScheduleSolution(solution);
          schedulingView.setSolution(solution);
        }
      };
      ioService.read(context, ScheduleSolution.class, model.key(), solutionDetailsCallback);
    }
    
  }
}
